package com.zx.security.block.handle;


import com.zx.core.wrapper.ResponseWrapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Collections;
import java.util.List;
import java.util.Optional;


/**
 * <p>
 * description: 全局异常处理<br>
 * create: 2024-08-23 13:48
 * </p>
 *
 * @author zhou  xun
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理权限不足异常
     *
     * @param e       异常信息
     * @param request 请求对象
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2025-05-14
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseWrapper handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        String requestURL = request.getRequestURI();
        log.warn("请求地址'{}',权限不足: {}", requestURL, e.getMessage());
        return buildErrorResponse("权限不足");
    }

    /**
     * 处理参数验证异常
     *
     * @param ex 异常信息
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2025-05-14
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseWrapper handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        List<ObjectError> globalErrors = Optional.of(bindingResult.getGlobalErrors()).orElse(Collections.emptyList());
        List<FieldError> fieldErrors = Optional.of(bindingResult.getFieldErrors()).orElse(Collections.emptyList());

        StringBuilder errorMessage = new StringBuilder();
        globalErrors.forEach(objectError -> {
            if (!errorMessage.isEmpty()) {
                errorMessage.append("; ");
            }
            errorMessage.append(objectError.getDefaultMessage());
        });
        fieldErrors.forEach(fieldError -> {
            if (!errorMessage.isEmpty()) {
                errorMessage.append("; ");
            }
            errorMessage.append(fieldError.getField()).append(": ").append(fieldError.getDefaultMessage());
        });

        return buildErrorResponse(errorMessage.toString());
    }

    /**
     * 处理运行时异常
     *
     * @param e       异常信息
     * @param request 请求对象
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2025-05-14
     */
    @ExceptionHandler(RuntimeException.class)
    public ResponseWrapper handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURL = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestURL, e);
        return buildErrorResponse(e.getMessage());
    }

    /**
     * 处理一般异常
     *
     * @param e       异常信息
     * @param request 请求对象
     * @return {@link ResponseWrapper}
     * @author zhou  xun
     * @since 2025-05-14
     */
    @ExceptionHandler(Exception.class)
    public ResponseWrapper handleGeneralException(Exception e, HttpServletRequest request) {
        String requestURL = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURL, e);
        return buildErrorResponse(e.getMessage());
    }

    // 私有辅助方法：构建统一响应对象
    private ResponseWrapper buildErrorResponse(String message) {
        ResponseWrapper result = new ResponseWrapper();
        result.fail(message);
        return result;
    }
}


